package com.surfilter.platform.base.util;

import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.processors.JsonValueProcessor;

import org.apache.log4j.Logger;

import com.surfilter.platform.base.exception.ExceptionBase;
import com.surfilter.platform.base.model.Constants;
import com.surfilter.platform.base.model.ResultCode;

public class ResultDataUtil {
	
	private static Logger log = Logger.getLogger(ResultDataUtil.class);
	
	private static final String CODE_TAG = "code";
	private static final String MSG_TAG = "msg";
	private static final String FLAG_TAG = "success";
	private static final String RESULT_DATA_TAG = "result";
	private static final String RESULT_COUNT_TAG = "total";

	static class DateJsonBeanProcessor implements JsonValueProcessor {
		private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

		public Object processArrayValue(Object arg0, JsonConfig arg1) {
			return "";
		}

		public Object processObjectValue(String arg0, Object arg1,
				JsonConfig arg2) {
			try {
				Date date = (Date) arg1;
				String str = dateFormat.format(date);
				return str;
			} catch (Exception e) {
				return "";
			}
		}
	}

	private final static JsonValueProcessor jvp = new DateJsonBeanProcessor();

	public static String getJsonData(Object object) {
		if(object instanceof String){
			return (String)object;
		}
		JsonConfig config = new JsonConfig();
		config.setIgnoreDefaultExcludes(false);
		config.registerJsonValueProcessor(Date.class, jvp);
		config.registerJsonValueProcessor(java.sql.Date.class, jvp);
		config.registerJsonValueProcessor(java.sql.Timestamp.class, jvp);
		if ((object instanceof Collection) || object.getClass().isArray()) {
			JSONArray retObject = JSONArray.fromObject(object, config);
			return retObject.toString(Constants.RESULT_JSON_LEVEL);
		} else {
			JSONObject retObject = JSONObject.fromObject(object, config);
			return retObject.toString(Constants.RESULT_JSON_LEVEL);
		}
	}

	public static String wrapResultData(Exception e) {
		JSONObject object = new JSONObject();
		object.put(FLAG_TAG, false);
		if (e instanceof ExceptionBase) {
			ExceptionBase baseE = (ExceptionBase) e;
			int code = baseE.getErrorCode();
			object.put(CODE_TAG, code);
			object.put(MSG_TAG, baseE.getCustomMsg());
		} else {
			object.put(CODE_TAG, ResultCode.SYSTEM_ERROR_CODE);
			object.put(MSG_TAG, e.getMessage());
		}
		String result = object.toString(Constants.RESULT_JSON_LEVEL);
		if(log.isDebugEnabled()){
			log.debug(result);
		}
		return result;
	}

	public static String wrapResultData(boolean res, int code, String msg,
			Object resultData, Map<String, Object> extraValues) {
		JSONObject object = new JSONObject();
		if (res) {
			code = ResultCode.SUCCESS;
		} else if (code == ResultCode.SUCCESS) {
			code = ResultCode.FAIL;
		}
		object.put(FLAG_TAG, res);
		object.put(CODE_TAG, code);
		object.put(MSG_TAG, msg);
		int total = 0;
		String result = "";
		if (resultData != null) {
			if ((resultData instanceof Collection))
				total = ((Collection) resultData).size();
			else if (resultData.getClass().isArray()) {
				total = ((Class[]) resultData).length;
			}
			result = getJsonData(resultData);
		}
		object.put(RESULT_COUNT_TAG, total);
		object.put(RESULT_DATA_TAG, result);
		if (extraValues != null)
			object.putAll(extraValues);
		String s = object.toString(Constants.RESULT_JSON_LEVEL);
		if(log.isDebugEnabled())
			log.debug(s);
		return s;
	}

	public static String wrapResultData(boolean res, int code, String msg,
			String jsonData, Map<String, Object> extraValues) {
		JSONObject object = new JSONObject();
		if (res) {
			code = ResultCode.SUCCESS;
		} else if (code == ResultCode.SUCCESS) {
			code = ResultCode.FAIL;
		}
		object.put(FLAG_TAG, res);
		object.put(CODE_TAG, code);
		object.put(MSG_TAG, msg);
		object.put(RESULT_DATA_TAG, jsonData);
		if (extraValues != null)
			object.putAll(extraValues);
		return object.toString(Constants.RESULT_JSON_LEVEL);
	}
}
